package com.ikingtech.platform.service.attachment.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ikingtech.framework.sdk.attachment.api.AttachmentApi;
import com.ikingtech.framework.sdk.attachment.model.AttachmentDTO;
import com.ikingtech.framework.sdk.attachment.model.AttachmentFileDTO;
import com.ikingtech.framework.sdk.attachment.model.AttachmentQueryParamDTO;
import com.ikingtech.framework.sdk.base.model.BatchParam;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.oss.api.OssApi;
import com.ikingtech.framework.sdk.oss.model.OssFileDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.service.attachment.entity.AttachmentDO;
import com.ikingtech.platform.service.attachment.service.AttachmentRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
@ApiController(value = "/attachment", name = "附件管理", description = "附件管理")
public class AttachmentController implements AttachmentApi {

    private final AttachmentRepository repo;

    private final OssApi ossApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Object> save(AttachmentDTO attachments) {
        this.repo.remove(Wrappers.<AttachmentDO>lambdaQuery().eq(AttachmentDO::getBusinessId, attachments.getBusinessId()));
        if (Tools.Coll.isNotBlank(attachments.getFiles())) {
            this.repo.saveBatch(Tools.Coll.convertList(attachments.getFiles(), attachmentFile -> {
                AttachmentDO entity = new AttachmentDO();
                entity.setId(Tools.Id.uuid());
                entity.setBusinessId(attachments.getBusinessId());
                entity.setBusinessGroup(attachmentFile.getBusinessGroup());
                entity.setOssFileId(attachmentFile.getOssFileId());
                if (null != attachmentFile.getType()) {
                    entity.setType(attachmentFile.getType().name());
                }
                return entity;
            }));
        }
        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Object> deleteBatch(BatchParam<String> businessIds) {
        if (Tools.Coll.isNotBlank(businessIds.getList())) {
            this.repo.remove(Wrappers.<AttachmentDO>lambdaQuery()
                    .in(AttachmentDO::getBusinessId, businessIds.getList()));
        }
        return R.ok();
    }

    @Override
    public R<AttachmentDTO> detail(String businessId) {
        // 通过ID获取附件实体
        List<AttachmentDO> entities = this.repo.list(Wrappers.<AttachmentDO>lambdaQuery().eq(AttachmentDO::getBusinessId, businessId));
        if (Tools.Coll.isBlank(entities)) {
            return R.ok(AttachmentDTO.notFound(businessId));
        }
        AttachmentDTO attachment = this.modelConvert(businessId, entities);
        // 返回附件详情
        return R.ok(attachment);
    }

    @Override
    public R<List<AttachmentDTO>> page(AttachmentQueryParamDTO queryParam) {
        return R.ok(PageResult.build(this.repo.page(new Page<>(queryParam.getPage(), queryParam.getRows()), Wrappers.<AttachmentDO>lambdaQuery()
                .in(Tools.Coll.isNotBlank(queryParam.getIds()), AttachmentDO::getId, queryParam.getIds())
                .like(Tools.Str.isNotBlank(queryParam.getBusinessId()), AttachmentDO::getBusinessId, queryParam.getBusinessId())
                .orderByDesc(AttachmentDO::getCreateTime))).convert(entity -> Tools.Bean.copy(entity, AttachmentDTO.class)));
    }

    /**
     * 获取所有附件信息
     *
     * @return 返回包含附件信息的列表
     */
    @Override
    public R<List<AttachmentDTO>> all() {
        return R.ok(this.modelConvert(this.repo.list()));
    }

    /**
     * 根据业务ID批量查询附件列表
     *
     * @param businessIds 业务ID列表
     * @return 查询结果
     */
    @Override
    public R<List<AttachmentDTO>> listByBusinessIds(BatchParam<String> businessIds) {
        return R.ok(this.modelConvert(this.repo.list(Wrappers.<AttachmentDO>lambdaQuery().in(AttachmentDO::getBusinessId, businessIds.getList()))));
    }

    private AttachmentDTO modelConvert(String businessId, List<AttachmentDO> entities) {
        List<OssFileDTO> ossFiles = this.ossApi.listByIds(BatchParam.build(Tools.Coll.convertList(entities, AttachmentDO::getOssFileId))).getData();
        Map<String, OssFileDTO> ossFileMap = Tools.Coll.convertMap(ossFiles, OssFileDTO::getId);
        AttachmentDTO attachment = new AttachmentDTO();
        attachment.setBusinessId(businessId);
        attachment.setFiles(Tools.Coll.convertList(entities, entity -> {
            AttachmentFileDTO attachmentFile = Tools.Bean.copy(entity, AttachmentFileDTO.class);
            if (ossFileMap.containsKey(entity.getOssFileId())) {
                OssFileDTO ossFile = ossFileMap.get(entity.getOssFileId());
                attachmentFile.setOriginName(ossFile.getOriginName());
                attachmentFile.setSuffix(ossFile.getSuffix());
                attachmentFile.setFileSize(ossFile.getFileSize());
                attachmentFile.setUrl(ossFile.getUrl());
            }
            return attachmentFile;
        }));
        return attachment;
    }

    private List<AttachmentDTO> modelConvert(List<AttachmentDO> entities) {
        Map<String, List<AttachmentDO>> attachmentMap = Tools.Coll.convertGroup(entities, AttachmentDO::getBusinessId);
        List<AttachmentDTO> result = new ArrayList<>();
        attachmentMap.forEach((businessId, attachmentEntities) -> result.add(this.modelConvert(businessId, attachmentEntities)));
        return result;
    }
}